package com.sanley.piss.web.service;


import com.sanley.piss.mapper.MenuMapper;
import com.sanley.piss.mapper.RoleAndResourceRelationMapper;
import com.sanley.piss.mapper.RoleMapper;
import com.sanley.piss.model.ServiceImpl;
import com.sanley.piss.model.StringUtil;
import com.sanley.piss.model.exceptionUtil.exception.ServiceException;
import com.sanley.piss.model.exceptionUtil.json.ResultEnum;
import com.sanley.piss.model.po.Menu;
import com.sanley.piss.model.po.Role;
import com.sanley.piss.model.po.RoleAndResourceRelation;
import com.sanley.piss.model.vo.MenuTree;
import com.sanley.piss.web.service.mapper.IMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 资源表业务层
 * 菜单父级ID默认为0
 * Create By  on 2021/3/6.
 *
 * @author 张凯大天才
 */
@Service
@Primary
@Transactional(rollbackFor = ServiceException.class)
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {

    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private RoleAndResourceRelationMapper roleAndResourceRelationMapper;

    /**
     * 增加菜单
     */


    /**
     * 增
     */
    @Override
    public void insert(Menu menu) {
        if (StringUtil.isNotNull(baseMapper.selectByTitle(menu.getTitle()))) {
            throw new ServiceException(ResultEnum.nameExist);
        }
        menu.setGmtCreate(LocalDateTime.now());
        if (baseMapper.insert(menu) != 0) {
            Role superAdmin = roleMapper.seletByCode("superadmin");
            if (StringUtil.isNull(superAdmin)) {
                throw new ServiceException("系统中没有超级管理员");
            }
            Set<Integer> integers = selectMenuIdsByParentId(menu.getId());
            integers.forEach(integer -> {
            roleAndResourceRelationMapper.insert(new RoleAndResourceRelation(superAdmin.getId(), menu.getId()));
            });
        }
    }

    /**
     * 修改
     *
     * @return
     */
    @Override
    public void updateById(Menu menu) {
        if (StringUtil.isNotNull(menu)) {
            List<Menu> lists = baseMapper.selectAllTitle();
            lists.forEach(list -> {
                if (menu.getTitle().equals(list.getTitle()) && !menu.getId().equals(list.getId())) {
                    throw new ServiceException("菜单已经存在");
                }
                if (menu.getPerCode().equals(list.getPerCode()) && !menu.getId().equals(list.getId())) {
                    throw new ServiceException("权限码已经存在");
                }
            });
            baseMapper.updateById(menu);
        }
        ;
    }

    /**
     * 删除
     *
     * @param ids
     * @return
     */
    @Override
    public void removeByIds(Integer[] ids) {
        Arrays.asList(ids).forEach(id -> {
            if (!baseMapper.listByParentId(id).isEmpty()) {
                throw new ServiceException("不允许删除");
            }
        });
        baseMapper.removeByIds(ids);
    }

    /**
     * 获得所有父级菜单
     */
    private void include(Set<Integer> set, Integer parentId) {
        Menu menu = baseMapper.selectById(parentId);
        if (StringUtil.isNotNull(menu)) {
            set.add(menu.getId());
            if (StringUtil.isNotNull(menu.getParentId()) && !Menu.DEFAULT_PARENT_VAL.equals(menu.getParentId())) {
                include(set, menu.getParentId());
            }
        }
    }

    @Override
    public Set<Integer> selectMenuIdsByParentId(Integer parentId) {
        Set<Integer> set = new HashSet<>();
        include(set, parentId);
        return set;
    }

    /**
     * 获取所有子菜单id
     */
    private void getSonIds(Set<Integer> set, Integer menuId) {
        List<Menu> menus = baseMapper.listByParentId(menuId);
        if (!menus.isEmpty()) {
            menus.forEach(menu -> {
                if (StringUtil.isNotNull(menu)) {
                    set.add(menu.getId());
                    getSonIds(set, menu.getId());
                }
            });
        }
    }

    @Override
    public Set<Integer> selectMenuSonIdsByMenuId(Integer menuId) {
        Set<Integer> set = new HashSet<>();
        getSonIds(set, menuId);
        return set;
    }

    @Override
    public List<MenuTree> selectUserMenuTree(Integer userId) {
        return baseMapper.selectUserMenuTree(userId);
    }

    @Override
    public List<Integer> selectUserMenuTreeIds(Integer userId) {
        return baseMapper.selectUserMenuTreeIds(userId);
    }

    @Override
    public Set<Integer> selectMenuIdByRoleId(Integer roleId) {
        Set<Integer> set = new HashSet<>();
        List<RoleAndResourceRelation> roleAndResourceRelations = roleAndResourceRelationMapper.selectListByRoleId(roleId);
        roleAndResourceRelations.forEach(role -> {
            set.add(role.getResourceId());
        });
        return set;
    }

    @Override
    public List<MenuTree> selectAllMenuTree() {
        return baseMapper.selectAllMenuTree();
    }

    @Override
    public Menu selectById(Integer id) {
        Menu selectOne = baseMapper.selectById(id);
        if (StringUtil.isNull(selectOne)) {
            throw new ServiceException("信息不存在");
        }
        return selectOne;
    }


}
